import React, {useState} from 'react';
import {useDispatch} from 'react-redux';
import {
    Avatar,
    Button,
    Checkbox,
    Container,
    FormControlLabel,
    Grid,
    IconButton,
    InputAdornment,
    Link,
    makeStyles,
    TextField,
    Typography,
    Paper
} from "@material-ui/core";
import {LockOutlined, Visibility, VisibilityOff} from '@material-ui/icons';
import {useFormik} from 'formik';
import * as yup from 'yup';

import {authFailure, authSuccess, checkAuthTimeout} from "../../store/actions/auth.actions";
import {signIn} from "../../shared/services/auth.service";
import {Alert} from "../../shared/components";
import withSpinner from "../../hoc/withSpinner";

const useStyles = makeStyles(theme => ({
    root: {
        display: 'flex',
        alignItems: 'center',
        height: '100vh'
    },
    paper: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        padding: theme.spacing(2)
    },
    avatar: {
        margin: theme.spacing(1),
        backgroundColor: theme.palette.primary.main
    },
    title: {
        fontWeight: 600,
        textTransform: 'uppercase',
        wordSpacing: '3px'
    },
    form: {
        width: '100%',
        marginTop: theme.spacing(1)
    },
    submit: {
        margin: theme.spacing(2, 0)
    },
    social_login_box: {
        marginTop: theme.spacing(1),
        marginBottom: theme.spacing(2),
        padding: theme.spacing(0, 0)
    },
    social_icon: {
        boxShadow: theme.shadows[2],
        backgroundColor: theme.palette.common.white
    },
    link_signUp: {
        '&:link, &:visited, &:active': {
            ...theme.typography.body2,
            textDecoration: 'none',
            color: theme.palette.primary.main
        },
        '&:hover': {
            textDecoration: 'underline'
        }
    }
}));

const validationSchema = yup.object({
    username: yup.string().required('Username is required'),
    password: yup.string().required('Password is required')
});

export default withSpinner(props => {
    const classes = useStyles();
    const dispatch = useDispatch();
    const auth = {
        success: (token) => dispatch(authSuccess(token)),
        failure: () => dispatch(authFailure()),
        checkTimeout: (expirationTime) => dispatch(checkAuthTimeout(expirationTime))
    };

    const [showPassword, setShowPassword] = useState(false);
    const [notification, setNotification] = useState({show: false, type: '', message: ''});

    const clearNotification = () => setNotification({show: false, type: '', message: ''});

    const loginForm = useFormik({
        initialValues: {
            username: 'saurabh',
            password: '12345678',
        },
        validationSchema: validationSchema,
        onSubmit: (values) => {
            clearNotification();
            const {username, password, client_id = 'Q8gKo8EsMCCclV7shMAs1fK0IrGZGP-AxDlqn5bfHJE'} = values;

            props.startSpinner();
            signIn(username, password, client_id).then(res => {
                props.stopSpinner();
                const expirationTime = new Date(new Date().getTime() + res.data.expires_in * 1000);
                localStorage.setItem('token', res.data.access_token);
                localStorage.setItem('expirationTime', expirationTime);
                auth.checkTimeout(res.data.expires_in);
                auth.success(res.data.access_token);
                props.history.push("/");
            }).catch(error => {
                props.stopSpinner();
                console.error(error);
                auth.failure();
                setNotification({
                    show: true,
                    type: 'error',
                    message: 'Username or Password is incorrect'
                });
            })
        }
    });

    return (
        <Container component="section" maxWidth="xs" className={classes.root}>
            <Paper elevation={4} className={classes.paper}>
                <Alert {...notification}/>

                <Avatar className={classes.avatar}><LockOutlined/></Avatar>

                <Typography component="h1" variant="h5" className={classes.title}>Sign in</Typography>

                <form className={classes.form} onSubmit={loginForm.handleSubmit}>
                    <TextField
                        id="username" name="username"
                        label="Username"
                        variant="outlined" margin="normal"
                        autoComplete="username"
                        fullWidth
                        value={loginForm.values.username}
                        onChange={loginForm.handleChange}
                        onBlur={loginForm.handleBlur}
                        error={loginForm.touched.username && Boolean(loginForm.errors.username)}
                        helperText={loginForm.touched.username && loginForm.errors.username}
                    />
                    <TextField
                        id="password" name="password"
                        label="Password"
                        variant="outlined" margin="normal"
                        autoComplete="current-password"
                        fullWidth
                        type={showPassword ? 'text' : 'password'}
                        InputProps={{
                            endAdornment: (
                                <InputAdornment position="end">
                                    <IconButton
                                        edge="end"
                                        onClick={() => setShowPassword(!showPassword)}
                                        onMouseDown={e => e.preventDefault()}
                                    >
                                        {showPassword ? <VisibilityOff/> : <Visibility/>}
                                    </IconButton>
                                </InputAdornment>
                            )
                        }}
                        value={loginForm.values.password}
                        onChange={loginForm.handleChange}
                        onBlur={loginForm.handleBlur}
                        error={loginForm.touched.password && Boolean(loginForm.errors.password)}
                        helperText={loginForm.touched.password && loginForm.errors.password}
                    />

                    <Grid container alignItems="center" justify="space-between">
                        <Grid item>
                            <FormControlLabel
                                control={<Checkbox value="remember" color="primary"/>}
                                label="Remember me"
                            />
                        </Grid>

                        <Grid item>
                            <Link href="#" variant="body1">Forgot password?</Link>
                        </Grid>
                    </Grid>

                    <Button type="submit" variant="contained" color="primary" className={classes.submit} fullWidth>
                        Sign In
                    </Button>
                </form>
            </Paper>
        </Container>
    );
});
